﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;


namespace RStudio.Command
{
    /// <summary>
    /// 命令 | 总端
    /// </summary>
    public class CommandManager : MonoBehaviour
    {
        /// <summary>
        /// 数据缓存
        /// </summary>
        private static readonly Dictionary<string, ICommand> _commands = new Dictionary<string, ICommand>();

        /// <summary>
        /// 事件 | 命令发布项
        /// </summary>
        public static event Action<string> OnCommandCommited;





        public void Init()
        {
            _commands.Clear();

            AutoRegisterCommands();
        }


        /// <summary>
        /// 命令注册
        /// </summary>
        /// <param name="command">命令实例</param>
        /// <param name="typeName">分支</param>
        /// <returns></returns>
        public static bool RegisterCommand(ICommand command)
        {
            if (command == null) return false;

            string key = command.Name.ToLower();
            bool isContain = CommandManager._commands.ContainsKey(key);

            if (isContain)
            {
                Debug.LogWarning($"命令重复: {command.Name} | {command.GetType().Name}");
                return false;
            }

            _commands.Add(key, command);

            Debug.Log($"命令注册成功: {key} - {command.Description}");

            return true;
        }

        /// <summary>
        /// 执行命令
        /// </summary>
        public bool TryExecuteCommand(string commandInput)
        {
            OnCommandCommited?.Invoke(commandInput);

            #region Tips | 处理空内容
            bool isEmpty = string.IsNullOrWhiteSpace(commandInput);
            if (isEmpty)
            {
                Debug.LogError("命令输入为空");
                return false;
            }
            #endregion

            #region Tips | 处理参数
            string[] parts = commandInput.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 0)
            {
                Debug.LogError("无效的命令格式");
                return false;
            }
            #endregion

            #region Tips | 查询命令有效性
            string commandKey = parts[0].ToLower();
            if (!_commands.TryGetValue(commandKey, out var command))
            {
                Debug.LogError($"未知命令: {commandKey}");
                return false;
            }
            #endregion

            #region Tips | 权限验证
            //if (!command.HasPermission(_currentContext.UserLevel))
            //{
            //    Debug.LogError($"权限不足，需要 {command.RequiredPermission} 权限");
            //    return false;
            //}
            #endregion

            // 执行命令（跳过命令关键字）
            string[] parameters = parts.Skip(1).ToArray();
            return command.Execute(parameters);
        }

        /// <summary>
        /// 获取权限组可用命令集
        /// </summary>
        public static IEnumerable<ICommand> GetAvailableCommands(CommandPermission userLevel)
        {
            return _commands.Values.Where(c => c.HasPermission(userLevel));
        }

        /// <summary>
        /// 获取 | 关联命令内容
        /// </summary>
        /// <param name="partialInput">输入项</param>
        /// <param name="userLevel">用户等级</param>
        /// <param name="maxSuggestions">最大数</param>
        /// <returns></returns>
        public static IEnumerable<ICommand> GetCommandSuggestions(
            string partialInput, 
            CommandPermission userLevel= CommandPermission.Normal, 
            int maxSuggestions = 50)
        {
            string inputLower = partialInput.ToLower();

            bool isEmpty = string.IsNullOrWhiteSpace(inputLower);

            if (isEmpty)
            {
                return Enumerable.Empty<ICommand>();
            }
            
            return GetAvailableCommands(userLevel)
                .Where(c => c.Name.ToLower().StartsWith(inputLower))
                .OrderBy(c => c.Name)
                .Take(maxSuggestions)
                .ToList();
        }


        /// <summary>
        /// 批量注册命令
        /// </summary>
        private void AutoRegisterCommands()
        {
            var commandTypes = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(assembly => assembly.GetTypes())
                .Where(type => typeof(ICommand).IsAssignableFrom(type) &&
                              !type.IsInterface && !type.IsAbstract);

            foreach (var type in commandTypes)
            {
                try
                {
                    ICommand command = Activator.CreateInstance(type) as ICommand;
                    RegisterCommand(command);
                }
                catch (Exception ex)
                {
                    Debug.LogError($"命令注册失败 | {type.Name}: {ex.Message}");
                }
            }
        }
    }
}